package com.zhengsr.drawbroad.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.zhengsr.drawbroad.data.StateData;
import com.zhengsr.drawbroad.state.BaseAction;
import com.zhengsr.drawbroad.state.PenAction;
import com.zhengsr.drawbroad.utils.BgUtils;
import com.zhengsr.drawbroad.utils.CommandUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Created by zhengshaorui on 2018/7/24.
 */

public class Surface extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "Surface";
    private SurfaceHolder mSurfaceHolder;
    private float mPreX,mPreY;
    private Path mPath ;
    private Paint mPaint;
    private Matrix mMatrix;
    private Bitmap mBg;
    private Paint mEraserPaint;
    private List<BaseAction> mBaseState = new ArrayList<>();
    private Executor executor = Executors.newFixedThreadPool(1);

    public Surface(Context context) {
        this(context,null);
    }

    public Surface(Context context, AttributeSet attrs) {
        super(context, attrs);
        mSurfaceHolder = getHolder();
        mSurfaceHolder.addCallback(this);
        setClickable(true);
        setFocusable(true);
        //init path and paint
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);
        mPaint.setColor(Color.BLUE);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true); //消除拉动
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mBitmap = Bitmap.createBitmap(1920,1080, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        mBg = BgUtils.drawGrayLineBg(1920,1080);
        mMatrix = new Matrix();
        mMatrix.postScale(1,1);

        //橡皮擦
        mEraserPaint = new Paint();
        mEraserPaint.setAntiAlias(true);
        mEraserPaint.setFilterBitmap(true);
        mEraserPaint.setStyle(Paint.Style.STROKE);
        mEraserPaint.setAlpha(0);
        mEraserPaint.setColor(Color.TRANSPARENT);
        mEraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        int max = 20*20 * 2;
        int paintwidth = (int) Math.pow(max,0.5);
        mEraserPaint.setStrokeWidth(paintwidth);

        mBaseState.add(PenAction.create());
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Canvas canvas = mSurfaceHolder.lockCanvas();
        canvas.drawBitmap(mBg,0,0,null);
        mSurfaceHolder.unlockCanvasAndPost(canvas);

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
               //  touchDown(event.getX(),event.getY());
                draw();
                 break;
            case MotionEvent.ACTION_MOVE:
                //touchMove(event.getX(),event.getY());
                draw();
                break;
            case MotionEvent.ACTION_UP:
               // touchUp();
                break;
            default :
                break;

        }
        return true;
    }

    /**
     * down 方法
     * @param x
     * @param y
     */
    private void touchDown(float x, float y) {
        if (mPath == null){
            mPath = new Path();
        }
        mPreX = x;
        mPreY = y;
        mPath.moveTo(x,y); //起点

    }

    /**
     *
     * @param x
     * @param y
     */
    private void touchMove(float x, float y) {

        float dx = Math.abs(x - mPreX);
        float dy = Math.abs(y - mPreY);
        if (dx >2 || dy >2){ //有移动时才画
            // 注意这里的mprex，虽然在down的时候，我们记录了mprex，但这里却是 move 的坐标
            // 所以，这里的quadto，其实是在移动时坐标的中点
            mPath.quadTo(mPreX,mPreY,(x + mPreX)/2,(y + mPreY)/2);
        }
        mPreX = x;
        mPreY = y;


    }
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private int type = 1;
     private void draw(){
         executor.execute(new Runnable() {
             @Override
             public void run() {
                 Canvas canvas = mSurfaceHolder.lockCanvas();
                 mCanvas.drawBitmap(mBg,mMatrix,null);

                     mCanvas.drawPath(mPath, mPaint);

                 canvas.drawBitmap(mBitmap,0,0,null);
                 // canvas.drawPath(mPath,mPaint);
                 mSurfaceHolder.unlockCanvasAndPost(canvas);
             }
         });


    }
     private void reDraw(){

        Canvas canvas = mSurfaceHolder.lockCanvas();
        List<StateData> baseDatas = CommandUtils.getInstance().getBaseState();
        if (!baseDatas.isEmpty()){
            for (StateData data : baseDatas) {
                mCanvas.drawBitmap(mBg,mMatrix,null);
                mCanvas.drawPath(data.path,data.paint);
                canvas.drawBitmap(mBitmap,0,0,null);
            }
        }else{
            mCanvas.drawBitmap(mBg,mMatrix,null);
            canvas.drawBitmap(mBitmap,0,0,null);
        }
        mSurfaceHolder.unlockCanvasAndPost(canvas);



    }


    private void touchUp() {
        Path cachepath = new Path(mPath);
        Paint paint = new Paint(mPaint);
        StateData data = new StateData(paint,cachepath);
        CommandUtils.getInstance().add(data);
       // mPath.reset();
    }
    public void undo(){
         if (!CommandUtils.getInstance().getBaseState().isEmpty()) {
             CommandUtils.getInstance().undo();
             reDraw();
         }
    }
    public void redo(){
        mPath.reset();
        CommandUtils.getInstance().redo();
        reDraw();
    }

    public void clear() {
        mPath.reset();
        CommandUtils.getInstance().clear();
        draw();
    }

    public void setEraser(int ss) {
        type = ss;
    }
}
